home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / dte5_1.zip / WINDOW.C < prev    next >
C/C++ Source or Header  |  1991-02-06  |  20KB  |  663 lines

  1. /*
  2.  * Written by Douglas Thomson (1989/1990)
  3.  *
  4.  * This source code is released into the public domain.
  5.  */
  6.  
  7. /*
  8.  * Name:    dte - Doug's Text Editor program - window module
  9.  * Purpose: This file contains the code associated with opening and sizing
  10.  *           windows, and also displaying the help window.
  11.  * File:    window.c
  12.  * Author:  Douglas Thomson
  13.  * System:  this file is intended to be system-independent
  14.  * Date:    October 12, 1989
  15.  */
  16.  
  17. #ifdef HPXL
  18. #include "commonh"
  19. #include "utilsh"
  20. #include "windowh"
  21. #else
  22. #include "common.h"
  23. #include "utils.h"
  24. #include "window.h"
  25. #endif
  26.  
  27. /*
  28.  * prototypes for all functions in this file
  29.  */
  30. int open_window ARGS((windows *window, char *name));
  31. void new_window ARGS((char *auto_name, windows *window));
  32. void choose_window ARGS((char *name, windows *window));
  33. void size_window ARGS((windows *window));
  34. void get_help ARGS((windows *window));
  35. void finish ARGS((windows *window));
  36. int create_window ARGS((windows *prev, int top, int bottom, text_ptr cursor,
  37.         file_infos *file));
  38. int create_file ARGS((file_infos *prev));
  39.  
  40. /*
  41.  * Name:    open_window
  42.  * Purpose: To open a new window, and load a file into it.
  43.  * Date:    October 10, 1989
  44.  * Passed:  window:   information allowing access to the current window
  45.  *          name:     name of file to read
  46.  * Returns: OK if window opened successfully
  47.  *          ERROR if anything went wrong
  48.  * Notes:   If window is NULL, then this is the first window, and should
  49.  *           take up the entire screen.
  50.  *          If window is not NULL, then the new window should start on the
  51.  *           line below the cursor line of the current window, and continue
  52.  *           down to what used to be the bottom of the current window. If
  53.  *           this does not make enough room for the new window, then an
  54.  *           error is reported, and no new window is created.
  55.  */
  56. int open_window(window, name)
  57. windows *window;
  58. char *name;
  59. {
  60.     int existing;       /* did the file already exist? */
  61.     file_infos *file;   /* file structure for file belonging to new window */
  62.     int ccol;           /* cursor column in new window */
  63.     text_ptr cursor;    /* start of cursor line in new window */
  64.     windows *wp;        /* used for scanning windows for same file name */
  65.     int file_attrib;    /* rwx bits for new file */
  66.  
  67.     if (window) {
  68.         /*
  69.          * check that there is room for the window (no need if this is the
  70.          *  first window)
  71.          */
  72.         if (window->bottom_line - window->cline < 2 ||
  73.                 g_display.nlines-3 - window->cline < 2) {
  74.             error(WARNING, "move cursor up first");
  75.             return ERROR;
  76.         }
  77.     }
  78.  
  79.     /*
  80.      * look for a window whose file has the same name. Check the
  81.      *  current window (if any) first.
  82.      * If there is already a window open on the same file, then the
  83.      *  new window can share the existing file structure, and the new
  84.      *  window's cursor should be placed in the same spot in the file.
  85.      */
  86.     if (window && strcmp(name, window->file_info->file_name) == 0) {
  87.         file = window->file_info;
  88.         existing = TRUE;
  89.         cursor = window->cursor;
  90.         ccol = window->ccol;
  91.  
  92.         /*
  93.          * One line is taken by the status line, and the cursor line
  94.          *  is duplicated. All the other lines can be kept.
  95.          */
  96.         window_scroll_down(window->cline+1, window->bottom_line);
  97.         window_scroll_down(window->cline+2, window->bottom_line);
  98.     }
  99.     else {
  100.         /*
  101.          * Not same file as current window, so try other windows
  102.          */
  103.         file = NULL;
  104.         for (wp=g_status.window_list; wp; wp = wp->next) {
  105.             if (strcmp(name, wp->file_info->file_name) == 0) {
  106.                 file = wp->file_info;
  107.                 break;
  108.             }
  109.         }
  110.         if (file) {
  111.             /*
  112.              * file was already open somewhere
  113.              */
  114.             existing = TRUE;
  115.             cursor = wp->cursor;
  116.             ccol = wp->ccol;
  117.         }
  118.         else {
  119.             /*
  120.              * file was not open, so see if it exists on disk
  121.              */
  122.             file_attrib = hw_fattrib(name);
  123.             existing = file_attrib != ERROR;
  124.             if (existing) {
  125.                 if (load_file(name, FALSE) != OK) {
  126.                     /*
  127.                      * The file existed, but was not a plain text file
  128.                      *  or we ran out of memory. In any case, give up
  129.                      *  on the new window.
  130.                      */
  131.                     return ERROR;
  132.                 }
  133.             }
  134.             else {
  135.                 /*
  136.                  * make sure this gets set properly even if there is no file!
  137.                  */
  138.                 g_status.temp_end = g_status.end_mem;
  139.             }
  140.  
  141.             /*
  142.              * allocate a file structure for the new file
  143.              */
  144.             if (create_file(window ? window->file_info : NULL) == ERROR) {
  145.                 error(WARNING, "out of memory");
  146.                 return ERROR;
  147.             }
  148.             file = window ? window->file_info->next : g_status.file_list;
  149.  
  150.             /*
  151.              * set up all the info we need to know about a file, and
  152.              *  record that we have used some more memory.
  153.              */
  154.             strcpy(file->file_name, name);
  155.             file->file_attrib = file_attrib;
  156.             cursor = g_status.end_mem;
  157.             ccol = 0;
  158.             file->start_text = g_status.end_mem;
  159.             *g_status.temp_end = '\0';
  160.             g_status.end_mem = g_status.temp_end + 1;
  161.             file->end_text = g_status.end_mem;
  162.  
  163.             /*
  164.              * file has not been modified yet
  165.              */
  166.             g_status.unsaved = FALSE;
  167.         }
  168.     }
  169.  
  170.     /*
  171.      * Now that we have the file, allocate a window to view the file
  172.      */
  173.     if (create_window(window, window ? window->cline+1 : 0,
  174.             window ? window->bottom_line : g_display.nlines-1, cursor,
  175.             file) == ERROR) {
  176.         error(WARNING, "out of memory");
  177.  
  178.         /*
  179.          * This is a real nuisance. We had room for the file and the
  180.          *  file structure, but not enough for the window as well.
  181.          * Now we must free all the memory that has already been
  182.          *  allocated.
  183.          */
  184.         if (file->ref_count == 0) {
  185.             if (file->prev) {
  186.                 file->prev->next = file->next;
  187.             }
  188.             else {
  189.                 g_status.file_list = file->next;
  190.             }
  191.             if (file->next) {
  192.                 file->next->prev = file->prev;
  193.             }
  194.             g_status.end_mem = file->start_text;
  195.             free(file);
  196.         }
  197.         return ERROR;
  198.     }
  199.  
  200.     if (window) {
  201.         /*
  202.          * record that the current window has lost some lines from
  203.          *  the bottom for the new window, and adjust its page size
  204.          *  etc accordingly.
  205.          */
  206.         window->bottom_line = window->cline;
  207.         setup_window(window);
  208.  
  209.         /*
  210.          * we have now finished with the old window, and can concentrate
  211.          *  on the new one.
  212.          */
  213.         window = window->next;
  214.     }
  215.     else {
  216.         window = g_status.window_list;
  217.     }
  218.  
  219.     /*
  220.      * tell the user if a new file has been created, in case this was not
  221.      *  intentional.
  222.      * Eventually, the user should be given a chance to change the name
  223.      *  of the file and try again.
  224.      */
  225.     if (!existing) {
  226.         error(DIAG, "'%s' is a new file", name);
  227.         file->new_file = TRUE;
  228.     }
  229.  
  230.     /*
  231.      * set up the new cursor position as appropriate
  232.      */
  233.     window->cursor = cursor;
  234.     window->ccol = ccol;
  235.  
  236.     /*
  237.      * the new window becomes the current window.
  238.      */
  239.     g_status.current_window = window;
  240.     return OK;
  241. }
  242.  
  243. /*
  244.  * Name:    new_window
  245.  * Purpose: To open a new window, and ask the user which file to load into it.
  246.  * Date:    October 10, 1989
  247.  * Passed:  auto_name: name of file (NULL if we should pr